﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
using System.Reflection.PortableExecutable;

namespace ApiData.JsonDB
{
    public class InitDB
    {
        private static ReaderWriterLockSlim tool = new ReaderWriterLockSlim();   // 读写锁
        private JArray db { get; set; }
        private string path { get; set; }
        /// <summary>
        /// 初始化JSON数据库
        /// </summary>
        /// <param name="path"></param>
        /// <exception cref="Exception"></exception>
        public InitDB(string path = "")
        {
            if (!string.IsNullOrWhiteSpace(path))
                this.path = path;
            using (TextReader file = System.IO.File.OpenText(path))
            {
                var text = file.ReadToEnd();
                if (string.IsNullOrWhiteSpace(text))
                    throw new Exception("json file is null");
                file.Close();
            }
            using (StreamReader reader = File.OpenText(path))
            {
                db = JArray.Parse(reader.ReadToEnd());
                reader.Close();
            }
        }
        /// <summary>
        /// 使用下标查询一个数据
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public object GetOfIndex(int index)
        {
            return db[index];
        }
        /// <summary>
        /// 查询所有数据
        /// </summary>
        /// <returns></returns>
        public object Select()
        {
            return db;
        }
        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <returns></returns>
        public object FirstOrDefault()
        {
            if (db != null)
                return db[0];
            else
                return null;
        }
        /// <summary>
        /// 查询符合条件的全部数据
        /// </summary>
        /// <param name="key">字段</param>
        /// <param name="value">值</param>
        /// <param name="count">返回数据量</param>
        /// <returns></returns>
        public object Where(string key, string value, out int count)
        {
            //Regex regex = new Regex("\\\"([\\S]+)\\\"\\s*:\\s*\\\"([\\S\\s]+?)\\\"");
            //List<object> list = new List<object>();
            //foreach (var item in db)
            //{
            //    var str = item.ToString().Replace("\r\n", "").Replace("\\n", "<br/>");
            //    MatchCollection res = regex.Matches(str);
            //    if (res.Count > 0)
            //    {
            //        Dictionary<string, string> dic = new Dictionary<string, string>();
            //        foreach (Match grp in res)
            //            dic.Add(grp.Groups[1].Value, grp.Groups[2].Value);

            //        if (dic.Keys.Any(x => x == key) && dic[key] == value)
            //            list.Add(dic);
            //    }
            //}
            //count = list.Count;
            //return list;

            var data = db.Where((x) =>
            {
                return x[key].ToString() == value;
            });
            count = data.Count();
            return data;
        }
        /// <summary>
        /// 模糊查询全部符合条件的数据
        /// </summary>
        /// <param name="key">字段</param>
        /// <param name="value">值</param>
        /// <param name="count">返回数据量</param>
        /// <returns></returns>
        public object WhereLike(string key, string value, out int count)
        {
            var data = db.Where((x) =>
            {
                return x[key].ToString().IndexOf(value) > -1;
            });
            count = data.Count();
            return data;
        }
        /// <summary>
        /// 查询第一条符合条件的数据
        /// </summary>
        /// <param name="key">字段</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        public object FirstOrDefault(string key, string value)
        {
            var data = db.FirstOrDefault((x) =>
            {
                return x[key].ToString().IndexOf(value) > -1;
            });
            return data;
        }
        /// <summary>
        /// 查询表数据量
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return db.Count;
        }
        /// <summary>
        /// 分页查询全部数据
        /// </summary>
        /// <param name="page">页索引</param>
        /// <param name="size">页大小</param>
        /// <returns></returns>
        public object Page(int page, int size)
        {
            var data = db.Skip((page - 1) * size).Take(size);
            return data;
        }
        /// <summary>
        /// 增加一条数据
        /// </summary>
        /// <param name="token">数据</param>
        /// <returns></returns>
        public bool insert(object token)
        {
            try
            {
                db.Add(token);
                var str = JsonConvert.SerializeObject(db);
                File.WriteAllText(path, str);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="token">数据</param>
        /// <param name="index">数据索引</param>
        /// <returns></returns>
        public bool update(JToken token, int index)
        {
            try
            {
                db[index] = token;
                var str = JsonConvert.SerializeObject(db);
                File.WriteAllText(path, str);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 删除一个数据
        /// </summary>
        /// <param name="index">数据索引</param>
        /// <returns></returns>
        public bool delete(int index)
        {
            try
            {
                var token = db[index];
                db.Remove(token);
                var str = JsonConvert.SerializeObject(db);
                File.WriteAllText(path, str);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 分组查询某一个字段的数据
        /// </summary>
        /// <param name="filed">数据分组字段</param>
        /// <returns></returns>
        public IEnumerable<string> distinct(string filed)
        {
            List<string> list = new List<string>();
            foreach (var obj in db)
                list.Add(obj[filed].ToString());
            return list.Distinct();
        }
    }
}
